#ifndef NET_BASE_CONNECTION_H
#define NET_BASE_CONNECTION_H

#include <hash_map>
#include <vector>
#include "base/basic_types.h"
#include "base/mutex.h"
#include "io/byte_stream.h"
#include "thread/executor.h"

using std::vector;
using __gnu_cxx::hash_map;

class ByteStream;
class PollRunner;

enum ConnectionStatus {
  UNKNOWN,
  CONNECTED,
  DISCONNECTED
};

struct ConnClient {
  int sockfd;
  ConnectionStatus status;
  Mutex byte_stream_mutex;
  ByteStream byte_stream;
};

class ServerConnection {
 public:
  ServerConnection(int port);
  void SetPollRunner(PollRunner* poll_runner);
  bool StartListen();
  virtual void HandleRead(int sockfd, char* buffer, int size) = 0;
  virtual void HandleConnect(int fd) = 0;
  virtual void HandleDisconnect(int fd) = 0;
  virtual void HandleWrite(int fd);
  virtual bool Send(int sockfd, const char* buffer, int size);

  void Disconnect(int fd);

  void set_backlog(int backlog);

 protected:
  ConnClient* GetClient(int fd);
  void CleanDisconnected();
  int sfd_;
  hash_map<int, ConnClient> clients_;
  Mutex clients_mutex_;

 private:
  int port_;
  int backlog_;
  PollRunner* poll_runner_;
  friend class PollRunner;
};

class PollRunner {
 public:
  PollRunner();
  void SetServerConnection(ServerConnection* conn);
  void Loop();
  void SetExit();

 private:
  ServerConnection* conn_;
  bool exit_;
};


#endif

